#pragma once

#include "halconcpp.h"
#include <vector>
#include <vector>
using namespace HalconCpp;

// 相机设备信息
struct s_CameraInfo
{
	std::string SN = "";                      //序列号
	std::string sDeviceUserID = "";           //使用名
	std::string sModelName = "";              //型号
	std::string IpAddr = "";                  //IP
};

//驱动信息
struct s_DevicesInfo
{
	int iNum;
	std::string sDevSource;
	s_CameraInfo sCameraInfo[20];
};


//旋转矩形结构体
struct s_Rect2X
{
	double fX;
	double fY;
	double fDeg;
	double fLength1;
	double fLength2;



	s_Rect2X()
	{
		fX = 0;
		fY = 0;
		fDeg = 0;
		fLength1 = 0;
		fLength2 = 0;

	}

	s_Rect2X DeepCopy()
	{
		s_Rect2X As;

		As.fX = fX;
		As.fY = fY;
		As.fDeg = fDeg;
		As.fLength1 = fLength1;
		As.fLength2 = fLength2;
		return As;
	}

	void Reset()
	{
		fX = 0;
		fY = 0;
		fDeg = 0;
		fLength1 = 0;
		fLength2 = 0;
	}

};


//平行矩形结构体
struct s_RectX
{
	double X1;
	double Y1;
	double X2;
	double Y2;



	s_RectX()
	{
		X1 = 0;
		Y1 = 0;
		X2 = 0;
		Y2 = 0;


	}

	s_RectX(double x1, double y1, double x2, double y2)
	{
		X1 = x1;
		Y1 = y1;
		X2 = x2;
		Y2 = y2;


	}


	s_RectX DeepCopy()
	{
		s_RectX As;

		As.X1 = X1;
		As.Y1 = Y1;
		As.X2 = X2;
		As.Y2 = Y2;
		return As;
	}

	void Reset()
	{
		X1 = 0;
		Y1 = 0;
		X2 = 0;
		Y2 = 0;
	}



};



//3D结构光相机图像
class s_Image3dS
{
public:
	HObject Gray;
	HObject Color;
	HObject X;
	HObject Y;
	HObject Z;
	HObject NX;
	HObject NY;
	HObject NZ;
	HTuple ObjectModel3D;
	long ID; //图像ID

	s_Image3dS()
	{
		GenEmptyObj(&Gray);
		GenEmptyObj(&Color);
		GenEmptyObj(&X);
		GenEmptyObj(&Y);
		GenEmptyObj(&Z);
		GenEmptyObj(&NX);
		GenEmptyObj(&NY);
		GenEmptyObj(&NZ);
		ObjectModel3D.Clear();
		ID = -1;
	}


	void Clear()
	{

		Gray.Clear();
		Color.Clear();
		X.Clear();
		Y.Clear();
		Z.Clear();
		NX.Clear();
		NY.Clear();
		NZ.Clear();

		if (ObjectModel3D.Length() > 0)
		{
			ClearObjectModel3d(ObjectModel3D);
			ObjectModel3D.Clear();
		}
		ID = -1;
	}


	s_Image3dS DeepCopy()
	{
		s_Image3dS As;

		//深拷贝
		if (Gray.IsInitialized() && Gray.CountObj() > 0) { As.Gray = Gray.Clone(); };
		if (Color.IsInitialized() && Color.CountObj() > 0) { As.Color = Color.Clone(); };
		if (X.IsInitialized() && X.CountObj() > 0) { As.X = X.Clone(); };
		if (Y.IsInitialized() && Y.CountObj() > 0) { As.Y = Y.Clone(); };
		if (Z.IsInitialized() && Z.CountObj() > 0) { As.Z = Z.Clone(); };
		if (NX.IsInitialized() && NX.CountObj() > 0) { As.NX = NX.Clone(); };
		if (NY.IsInitialized() && NY.CountObj() > 0) { As.NY = NY.Clone(); };
		if (NZ.IsInitialized() && NZ.CountObj() > 0) { As.NZ = NZ.Clone(); };

		if (ObjectModel3D.Length() > 0)
		{
			CopyObjectModel3d(ObjectModel3D, "all", &As.ObjectModel3D);
		}

		As.ID = ID;

		return As;
	}


};





//预处理图像输入-3DS
class s_PreProcess3DSPara
{
public:
	double fRoiZMin;            //空间ROI区域范围
	double fRoiZMax;
	double fRoiXMin;
	double fRoiXMax;
	double fRoiYMin;
	double fRoiYMax;

	double fThSeg0Dis;              //初步分割  领域距离值  聚点数量选择 直径选择等
	int iThSeg0NumPtsMin;
	int iThSeg0NumPtsMax;
	double fThSeg0DiameterMin;
	double fThSeg0DiameterMax;


	bool bUseDisToPlane;           //进一步分割--使用到平面的距离
	double fSampleDtp = 10;
	double fThSegAngleDtp = 1.5;
	double fThSegDisDtp = 10;
	double fPtsSelToPlaneDisMin = 3;
	double fPtsSelToPlaneDisMax = 100;
	double fThSeg2DisDtp = 5;
	int iThSeg2NumPtsMinDtp = 5000;
	int iThSeg2NumPtsMaxDtp = 5000000;


	s_PreProcess3DSPara()
	{
		fRoiZMin = 0.0; //空间ROI区域范围
		fRoiZMax = 0.0;
		fRoiXMin = 0.0;
		fRoiXMax = 0.0;
		fRoiYMin = 0.0;
		fRoiYMax = 0.0;

		fThSeg0Dis = 0.0;              //初步分割  领域距离值  聚点数量选择 直径选择  Y方向聚类长度限制值等
		iThSeg0NumPtsMin = 0;
		iThSeg0NumPtsMax = 0;
		fThSeg0DiameterMin = 0.0;
		fThSeg0DiameterMax = 0.0;

		bUseDisToPlane = false;
		fSampleDtp = 10;
		fThSegAngleDtp = 1.5;
		fThSegDisDtp = 10;
		fPtsSelToPlaneDisMin = 3;
		fPtsSelToPlaneDisMax = 100;
		fThSeg2DisDtp = 5;
		iThSeg2NumPtsMinDtp = 5000;
		iThSeg2NumPtsMaxDtp = 5000000;
	}


	s_PreProcess3DSPara DeepCopy()
	{
		s_PreProcess3DSPara As;

		As.fRoiZMin = fRoiZMin;
		As.fRoiZMax = fRoiZMax;
		As.fRoiXMin = fRoiXMin;
		As.fRoiXMax = fRoiXMax;
		As.fRoiYMin = fRoiYMin;
		As.fRoiYMax = fRoiYMax;

		As.fThSeg0Dis = fThSeg0Dis;              //初步分割  领域距离值  聚点数量选择 直径选择  Y方向聚类长度限制值等
		As.iThSeg0NumPtsMin = iThSeg0NumPtsMin;
		As.iThSeg0NumPtsMax = iThSeg0NumPtsMax;
		As.fThSeg0DiameterMin = fThSeg0DiameterMin;
		As.fThSeg0DiameterMax = fThSeg0DiameterMax;

		As.bUseDisToPlane = bUseDisToPlane;
		As.fSampleDtp = fSampleDtp;
		As.fThSegAngleDtp = fThSegAngleDtp;
		As.fThSegDisDtp = fThSegDisDtp;
		As.fPtsSelToPlaneDisMin = fPtsSelToPlaneDisMin;
		As.fPtsSelToPlaneDisMax = fPtsSelToPlaneDisMax;
		As.fThSeg2DisDtp = fThSeg2DisDtp;
		As.iThSeg2NumPtsMinDtp = iThSeg2NumPtsMinDtp;
		As.iThSeg2NumPtsMaxDtp = iThSeg2NumPtsMaxDtp;


		return As;
	}

};


//预处理图像结果-3DS
class s_PreProcess3DSResultPara
{

public:
	bool bTJG;          //综合判断
	double time;
	s_Image3dS sImage3dPro;  //处理后的图像

	s_PreProcess3DSResultPara()
	{
		bTJG = false;
		time = 0.0;

	}

	s_PreProcess3DSResultPara DeepCopy()
	{
		s_PreProcess3DSResultPara As;

		As.bTJG = bTJG;
		As.time = time;
		As.sImage3dPro = sImage3dPro.DeepCopy();
		return As;
	}
};




//
//阴极板缺陷参数
class s_DefectPlateBPara
{
public:
	double fThNZAbsVal;  //提取铜板法线参数


	double fQgOffsetL;  //上下左右气缸区域伸出偏移
	double fQgOffsetR;
	double fQgOffsetU;
	double fQgOffsetD;


	double fThBulgeLowerC; //中心区粒子提取阈值1
	double fThBulgeHigerC;//中心区粒子提取阈值2
	double fThBulgeLowerS;//边缘区粒子提取阈值1
	double fThBulgeHigerS;//边缘区粒子提取阈值2

	double fQgThOffset;  //气缸高度偏差提取阈值

	double fQgLHOrg;     //左气缸原始高度
	double fQgLExCol;    //左气缸X扩展
	double fQgLExRow;    //左气缸Y扩展

	double fQgRHOrg;
	double fQgRExCol;
	double fQgRExRow;

	double fQgUHOrg;
	double fQgUExCol;
	double fQgUExRow;

	double fQgDHOrg;
	double fQgDExCol;
	double fQgDExRow;

	double fRenderRangeScale; //高度渲染系数

	double fConnectionDis;   //聚类分割距离mm

	s_DefectPlateBPara()
	{
		
	}

	s_DefectPlateBPara DeepCopy()
	{
		s_DefectPlateBPara As;

		As.fThNZAbsVal = fThNZAbsVal;


		As.fQgOffsetL = fQgOffsetL;
		As.fQgOffsetR = fQgOffsetR;
		As.fQgOffsetU = fQgOffsetU;
		As.fQgOffsetD = fQgOffsetD;


		As.fThBulgeLowerC = fThBulgeLowerC;
		As.fThBulgeHigerC = fThBulgeHigerC;

		As.fThBulgeLowerS = fThBulgeLowerS;
		As.fThBulgeHigerS = fThBulgeHigerS;

		As.fQgThOffset = fQgThOffset;

		As.fQgLHOrg = fQgLHOrg;
		As.fQgLExCol = fQgLExCol;
		As.fQgLExRow = fQgLExRow;
		
		As.fQgRHOrg = fQgRHOrg;
		As.fQgRExCol = fQgRExCol;
		As.fQgRExRow = fQgRExRow;

		As.fQgUHOrg = fQgUHOrg;
		As.fQgUExCol = fQgUExCol;
		As.fQgUExRow = fQgUExRow;

		As.fQgDHOrg = fQgDHOrg;
		As.fQgDExCol = fQgDExCol;
		As.fQgDExRow = fQgDExRow;

		As.fConnectionDis = fConnectionDis;

		return As;
	}

};

//阴极板缺陷结果参数
class s_DefectPlateBRtsPara
{
public:
	bool bTJG;         //综合判断
	double time;

	HTuple PoseTb;  //铜板调平Pose

	HObject X1;  //图像坐标系--原始图像X-铜板区域
	HObject Y1;  //图像坐标系--原始图像Y-铜板区域
	HObject Z1;  //图像坐标系--原始图像Z-铜板区域

	HObject Z1PZero; //图像调零坐标系--原始图像X-铜板区域
	HObject X1PZero; //图像调零坐标系--原始图像Y-铜板区域
	HObject Y1PZero; //图像调零坐标系--原始图像Y-铜板区域

	HObject ImageSubZ1;  //高度图--相对周边区域
	HObject ImageZ1ZeroReal; //高度图--相对整个零平面

	HObject NzRender; //法线渲染图
	HObject ZTbRender; //铜板区域高度渲染图
	HObject ZLzRender; //粒子区域高度渲染图

	HObject RegionBulge;    //粒子区域
	HObject RectPartLz;     //加工区域Rect
	HObject RegionTb;       //铜板区域
	HObject RectangleQgSort;  //排序后的气缸区域

	HObject RectPartLzC; //板子分区-中间和上下左右
	HObject RectPartLzL;
	HObject RectPartLzU;
	HObject RectPartLzD;
	HObject RectPartLzR;


	HTuple OM3ImageAdv;      //处理后的3d点云 

	
	s_DefectPlateBRtsPara()
	{
		bTJG = false;
		time = 0.0;

		//数值结果
		PoseTb.Clear();

		//2D结果
		GenEmptyObj(&X1);
		GenEmptyObj(&Y1);
		GenEmptyObj(&Z1);
		GenEmptyObj(&Z1PZero);
		GenEmptyObj(&X1PZero);
		GenEmptyObj(&Y1PZero);

		GenEmptyObj(&ImageSubZ1);
		GenEmptyObj(&ImageZ1ZeroReal);

		GenEmptyObj(&NzRender);
		GenEmptyObj(&ZTbRender);
		GenEmptyObj(&ZLzRender);

		GenEmptyObj(&RegionBulge);
		
		GenEmptyObj(&RectPartLz);
	
		GenEmptyObj(&RegionTb);
	

		GenEmptyObj(&RectangleQgSort);


		GenEmptyObj(&RectPartLzC);
		GenEmptyObj(&RectPartLzL);
		GenEmptyObj(&RectPartLzU);
		GenEmptyObj(&RectPartLzD);
		GenEmptyObj(&RectPartLzR);


		//3D结果  
		GenEmptyObjectModel3d(&OM3ImageAdv);


	}


	s_DefectPlateBRtsPara DeepCopy()
	{
		s_DefectPlateBRtsPara As;


		As.bTJG = bTJG;
		As.time = time;

		As.PoseTb = HTuple(PoseTb);

		//2D


		if (X1.IsInitialized() && X1.CountObj() > 0) { As.X1 = X1.Clone(); };
		if (Y1.IsInitialized() && Y1.CountObj() > 0) { As.Y1 = Y1.Clone(); };
		if (Z1.IsInitialized() && Z1.CountObj() > 0) { As.Z1 = Z1.Clone(); };
		if (Z1PZero.IsInitialized() && Z1PZero.CountObj() > 0) { As.Z1PZero = Z1PZero.Clone(); };
		if (X1PZero.IsInitialized() && X1PZero.CountObj() > 0) { As.X1PZero = X1PZero.Clone(); };
		if (Y1PZero.IsInitialized() && Y1PZero.CountObj() > 0) { As.Y1PZero = Y1PZero.Clone(); };

		if (NzRender.IsInitialized() && NzRender.CountObj() > 0) { As.NzRender = NzRender.Clone(); };
		if (ZTbRender.IsInitialized() && ZTbRender.CountObj() > 0) { As.ZTbRender = ZTbRender.Clone(); };
		if (ZLzRender.IsInitialized() && ZLzRender.CountObj() > 0) { As.ZLzRender = ZLzRender.Clone(); };

		if (ImageSubZ1.IsInitialized() && ImageSubZ1.CountObj() > 0) { As.ImageSubZ1 = ImageSubZ1.Clone(); };
		if (ImageZ1ZeroReal.IsInitialized() && ImageZ1ZeroReal.CountObj() > 0) { As.ImageZ1ZeroReal = ImageZ1ZeroReal.Clone(); };


		if (RegionBulge.IsInitialized() && RegionBulge.CountObj() > 0) { As.RegionBulge = RegionBulge.Clone(); };
		if (RectPartLz.IsInitialized() && RectPartLz.CountObj() > 0) { As.RectPartLz = RectPartLz.Clone(); };

		if (RectangleQgSort.IsInitialized() && RectangleQgSort.CountObj() > 0) { As.RectangleQgSort = RectangleQgSort.Clone(); };

		if (RegionTb.IsInitialized() && RegionTb.CountObj() > 0) { As.RegionTb = RegionTb.Clone(); };
		
		if (RectPartLzC.IsInitialized() && RectPartLzC.CountObj() > 0) { As.RectPartLzC = RectPartLzC.Clone(); };
		if (RectPartLzL.IsInitialized() && RectPartLzL.CountObj() > 0) { As.RectPartLzL = RectPartLzL.Clone(); };
		if (RectPartLzU.IsInitialized() && RectPartLzU.CountObj() > 0) { As.RectPartLzU = RectPartLzU.Clone(); };
		if (RectPartLzD.IsInitialized() && RectPartLzD.CountObj() > 0) { As.RectPartLzD = RectPartLzD.Clone(); };
		if (RectPartLzR.IsInitialized() && RectPartLzR.CountObj() > 0) { As.RectPartLzR = RectPartLzR.Clone(); };





		// 3D

		if (OM3ImageAdv.Length() > 0)
		{
			try { CopyObjectModel3d(OM3ImageAdv, "all", &As.OM3ImageAdv); }
			catch (...) { ; }

		}

		return As;
	}

	

	void Reset()
	{
		bTJG = false;
		time = 0.0;

		PoseTb.Clear();

		//2D
		X1.Clear();
		Y1.Clear();
		Z1.Clear();
		Z1PZero.Clear();
		X1PZero.Clear();
		Y1PZero.Clear();

		NzRender.Clear();
		ZTbRender.Clear();
		ZLzRender.Clear();

		ImageSubZ1.Clear();
		ImageZ1ZeroReal.Clear();

		RectPartLz.Clear();
		RectangleQgSort.Clear();

		RegionTb.Clear();



		GenEmptyObj(&X1);
		GenEmptyObj(&Y1);
		GenEmptyObj(&Z1);
		GenEmptyObj(&Z1PZero);
		GenEmptyObj(&X1PZero);
		GenEmptyObj(&Y1PZero);

		GenEmptyObj(&ImageSubZ1);
		GenEmptyObj(&ImageZ1ZeroReal);

		GenEmptyObj(&NzRender);
		GenEmptyObj(&ZTbRender);
		GenEmptyObj(&ZLzRender);

		GenEmptyObj(&RectPartLz);
		GenEmptyObj(&RegionBulge);
		GenEmptyObj(&RectangleQgSort);
		GenEmptyObj(&RegionTb);
		

		GenEmptyObj(&RectPartLzC);
		GenEmptyObj(&RectPartLzL);
		GenEmptyObj(&RectPartLzU);
		GenEmptyObj(&RectPartLzD);
		GenEmptyObj(&RectPartLzR);


		//3D结果  
		GenEmptyObjectModel3d(&OM3ImageAdv);


		//3D
		if (OM3ImageAdv.Length() > 0)
		{
			ClearObjectModel3d(OM3ImageAdv);
			OM3ImageAdv.Clear();
		}


	
	}

	//获取粒子数量
	int GetLzNum()
	{

		HTuple hNum;
		HalconCpp::CountObj(RegionBulge, &hNum);
		

		return hNum[0].I();
	}


	//获取粒子面积
	double GetLzAreaTotalMM()
	{
		double fAreaMM=0;



		try
		{
			HObject RegionUnion;
			HTuple hv_Row, hv_Column, hv_Area;
			HalconCpp::Union1(RegionBulge, &RegionUnion);
			HalconCpp::AreaCenter(RegionUnion, &hv_Area, &hv_Row, &hv_Column);

			double fResolution = GetResolution();
			fAreaMM = hv_Area[0].D() * fResolution * fResolution;
		}
		catch (...)
		{

		}

		return fAreaMM;
	}

	double GetResolution()
	{
		//计算像素分辨率

		double fResolution = 0.01;

		try
		{
			HObject  ho_RegionIntersection;
			HalconCpp::Intersection(RegionTb, X1, &ho_RegionIntersection);

			HTuple hv_Min, hv_Max, hv_Range;
			MinMaxGray(ho_RegionIntersection, X1, 0, &hv_Min, &hv_Max, &hv_Range);
			double fRangeX = hv_Range[0].D();


			HTuple hv_Row1, hv_Column1;
			HTuple hv_Row2, hv_Column2;
			SmallestRectangle1(ho_RegionIntersection, &hv_Row1, &hv_Column1, &hv_Row2, &hv_Column2);
			double fRangePixelX = hv_Column2[0].D() - hv_Column1[0].D();

			fResolution = abs(fRangeX / fRangePixelX);
		}
		catch (HalconCpp::HException& ex)
		{
				
		}


		return fResolution;
	}

	//获取粒子最大高度 mm
	double GetLzHeightMax()
	{
		double fHeightMax = 0;

		try
		{

			HObject RegionUnion;
			HTuple hv_Row, hv_Column, hv_Area;
			HalconCpp::Union1(RegionBulge, &RegionUnion);

			HObject  ho_RegionIntersection;

			HalconCpp::Intersection(RegionUnion, ImageZ1ZeroReal, &ho_RegionIntersection);

			HTuple hv_Min, hv_Max, hv_Range;
		HalconCpp:MinMaxGray(ho_RegionIntersection, ImageZ1ZeroReal, 0, &hv_Min, &hv_Max, &hv_Range);

			fHeightMax = hv_Max[0].D();



		}

		catch (HalconCpp::HException& ex)
		{

		}




		return fHeightMax;

	}


	//获取粒子块体积的总体积 mm2
	double GetPartLzVolumeATotal()
	{
		double fVolumeAll = 0;


		try
		{
			HTuple hNum;
			CountObj(RegionBulge, &hNum);

			for (int i = 0; i < hNum[0].I(); i++)
			{
				HObject ho_ObjectSelected, ho_RegionIntersection;
				SelectObj(RegionBulge, &ho_ObjectSelected, i + 1);
				Intersection(ho_ObjectSelected, ImageZ1ZeroReal, &ho_RegionIntersection);

				HTuple hv_Min, hv_Max, hv_Range;
				MinMaxGray(ho_RegionIntersection, ImageZ1ZeroReal, 0, &hv_Min, &hv_Max, &hv_Range);

				double ZHeight = hv_Range[0].D();

				Intersection(ho_ObjectSelected, ImageZ1ZeroReal, &ho_RegionIntersection);
		MinMaxGray(ho_RegionIntersection, X1, 0, &hv_Min, &hv_Max, &hv_Range);
				double LenX = hv_Range[0].D();


				Intersection(ho_ObjectSelected, ImageZ1ZeroReal, &ho_RegionIntersection);
				MinMaxGray(ho_RegionIntersection, Y1, 0, &hv_Min, &hv_Max, &hv_Range);
				double LenY = hv_Range[0].D();


				double fVolume = LenY * LenX * ZHeight;
				fVolumeAll += fVolume;
			}

		}

		catch (HalconCpp::HException& ex)
		{

		}




		return fVolumeAll;

	}


	//获取粒子的子矩形区域
	std::vector<s_RectX> GetRectsLz()
	{
		std::vector<s_RectX> rects;

		try
		{
			HTuple hv_Row1, hv_Column1;
			HTuple hv_Row2, hv_Column2;
			SmallestRectangle1(RegionBulge, &hv_Row1, &hv_Column1, &hv_Row2, &hv_Column2);


			for (size_t i = 0; i < hv_Row1.Length(); i++)
			{
				rects.push_back(s_RectX(hv_Column1[i].D(), hv_Row1[i].D(), hv_Column2[i].D(), hv_Row2[i].D()));
			}
		}

		catch (HalconCpp::HException& ex)
		{

		}


		return rects;
	}


	//获取粒子块的矩形区域
	std::vector<s_RectX> GetRectsPartLz() 
	{
		std::vector<s_RectX> rects;

		try
		{
			HTuple hv_Row1, hv_Column1;
			HTuple hv_Row2, hv_Column2;
			SmallestRectangle1(RectPartLz, &hv_Row1, &hv_Column1, &hv_Row2, &hv_Column2);


			for (size_t i = 0; i < hv_Row1.Length(); i++)
			{
				rects.push_back(s_RectX(hv_Column1[i].D(), hv_Row1[i].D(), hv_Column2[i].D(), hv_Row2[i].D()));
			}


		}

		catch (HalconCpp::HException& ex)
		{

		}

		return rects;


	}


};




//加工工艺参数
struct  s_JggyPara
{

	double fDjDiamiter;  //刀具直径
	double fJgLzUpOffset;  //粒子最高点上抬距离 作为最高点
	double fJgDpUpOffset; //铜板上平面上抬距离作为最低点
	int iModeJgPPZStepMode;//规划Z路径进给模式  0 :等距进给 1：线性进给
	double fJgPPZStepFix;  //固定进给Z
	double fJgPPZStepK;    //线性进给Z的直线系数 K B
	double fJgPPZStepB;

	double fJgPPZStepMin;   //线性进给Z最小值
	double fJgPPZStepMax;   //线性进给Z最大值

	int iModeJgPPYStepMode; //规划Y路径进给模式  0 :固定进给 1：根据刀盘大小进给
	double fJgPPYStepFix;   //固定进给距离
	double fJgPPYStepK;    //线性进给距离--刀盘直径系数
	int iModeJgPPSort;   //粒子加工排序 //*粒子加工排序 0：从上到下 1：从下到上   2 ：从左到右  3 ：从右到左 4：局部最近 5：全局最短
	double fQgSafeDis;  //气缸安全距离  注意此处考虑的是加工中心点到气缸的安全距离，未考虑刀盘直径影响
	double fJgTdZUp;    //抬刀高度 用于起始点 或者终点 加工完后的上抬高度

	double fOffsetCutStartPos; //下刀位置偏移
	double fOffsetBothEndsL; //路径段左偏移
	double fOffsetBothEndsR;//路径段右偏移


	double fOffsetPtsX = 0; //路径点整体偏移X  --机床坐标系下的补偿 补偿方向和机床坐标系一致
	double fOffsetPtsY = 0; //路径点整体偏移Y 
	double fOffsetPtsZ = 0; //路径点整体偏移Z   测试时 将Z加一个较大向上高度 便于观察路径点是否准确 精调时 可以用作略微修正Z轴坐标（±2mm以内）



};

//路径点位结构体
struct s_PPts
{

	double fX; //坐标点
	double fY;
	double fZ;
	int iDef; //点属性定义  1 起点  2 终点  3 中间点  4空跑点
	double fRow;  //图像行坐标
	double fCol;  //图像列坐标
	std::string strQgNotSafe; //避让气缸索引  eg "0,2,4" 代表第1,3,5个气缸需要松开

	double ZMaxRelDm;
	double MxHeightCur;

	int indexLz;


	s_PPts()
	{
		fX = 0;
		fY = 0;
		fZ = 0;
		iDef = 0;
		fRow = 0;
		fCol = 0;
		strQgNotSafe = "";
	    ZMaxRelDm = 0;
	    MxHeightCur = 0;
		indexLz = -1;

	}



	void Reset()
	{
		fX = 0;
		fY = 0;
		fZ = 0;
		iDef = 0;
		fRow = 0;
		fCol = 0;
		strQgNotSafe = "";

		ZMaxRelDm = 0;
		MxHeightCur = 0;

		indexLz = -1;
	}

};




//粒子路径规划结果参数结果参数
class s_LzppRtsPara
{
public:
	bool bTJG;         //综合判断
	double time;
	int iNumPts;     
	std::vector<s_PPts> sListPPtsImage;  //图像坐标系下的点位
	std::vector<s_PPts> sListPPtsRobot;  //机床坐标系下的点位
	HObject RegionMxAllList;             //规划后的图像加工区域

	s_LzppRtsPara()
	{
		bTJG = false;
		time = 0.0;

		iNumPts = 0;
		sListPPtsImage = {};
		sListPPtsRobot = {};
		GenEmptyObj(&RegionMxAllList);
	}


	s_LzppRtsPara DeepCopy()
	{
		s_LzppRtsPara As;


		As.bTJG = bTJG;
		As.time = time;

		As.iNumPts = iNumPts;
		As.sListPPtsImage.clear();
		for (int i = 0; i < sListPPtsImage.size(); i++)
		{
			As.sListPPtsImage.push_back(sListPPtsImage[i]);
		}

		for (int i = 0; i < sListPPtsRobot.size(); i++)
		{
			As.sListPPtsRobot.push_back(sListPPtsRobot[i]);
		}



		if (RegionMxAllList.IsInitialized() && RegionMxAllList.CountObj() > 0) { As.RegionMxAllList = RegionMxAllList.Clone(); };

		return As;
	}

	void Reset()
	{
		bTJG = false;
		time = 0.0;

		iNumPts = 0;
		sListPPtsImage.clear();
		sListPPtsRobot.clear();
		GenEmptyObj(&RegionMxAllList);

	}


	//获取加工进度比 【0,100】 根据当前加工点的索引
 	double getProcessingPercentage(int indexPts)
	{
		if (sListPPtsRobot.size()==0)
		{
			return 100;
		}


		if (indexPts<0)
		{
			return 0;
		}

		return indexPts*100.0/ sListPPtsRobot.size() ;

	}


};



// 标定-- 相机坐标系转机床坐标系转换pose
class s_PoseH
{
public:

	double fTransX; //平移XYZ
	double fTransY;
	double fTransZ;
	double fRotX;  //旋转XYZ
	double fRotY;
	double fRotZ;
	int  dwType;  //类型


	s_PoseH()
	{
		fTransX = 0.0;
		fTransY = 0.0;
		fTransZ = 0.0;
		fRotX = 0.0;
		fRotY = 0.0;
		fRotZ = 0.0;
		dwType = 0;
	}

	s_PoseH(double X, double Y, double Z, double RX, double RY, double RZ, int dw)
	{
		fTransX = X;
		fTransY = Y;
		fTransZ = Z;
		fRotX = RX;
		fRotY = RY;
		fRotZ = RZ;
		dwType = dw;
	}

	bool IsAvailable()
	{
		if (fRotX == 0 && fRotY == 0 && fRotZ == 0)
		{
			return false;
		}

		if (fTransX == 0 && fTransY == 0 && fTransZ == 0)
		{
			return false;
		}

		return true;
	}


	HTuple  ToTuple()
	{


		HTuple hh;

		hh.Clear();
		hh[0] = fTransX;
		hh[1] = fTransY;
		hh[2] = fTransZ;
		hh[3] = fRotX;
		hh[4] = fRotY;
		hh[5] = fRotZ;
		hh[6] = dwType;

		return  hh;


	}

	s_PoseH(HTuple h)
	{
		try
		{
			fTransX = h[0].D();
			fTransY = h[1].D();
			fTransZ = h[2].D();
			fRotX = h[3].D();
			fRotY = h[4].D();
			fRotZ = h[5].D();
			dwType = h[6].I();
		}
		catch (HOperatorException ex)
		{

			fTransX = 0.0;
			fTransY = 0.0;
			fTransZ = 0.0;
			fRotX = 0.0;
			fRotY = 0.0;
			fRotZ = 0.0;
			dwType = 0;
		}

	}

	s_PoseH ToGba()
	{
		s_PoseH PoseH;;

		try
		{

			HTuple h1, h2;

			h1.Clear();
			h1[0] = fTransX;
			h1[1] = fTransY;
			h1[2] = fTransZ;
			h1[3] = fRotX;
			h1[4] = fRotY;
			h1[5] = fRotZ;
			h1[6] = dwType;

			ConvertPoseType(h1, "Rp+T", "gba", "point", &h2);
			PoseH = s_PoseH(h2);
		}
		catch (HOperatorException ex)
		{

		}


		return PoseH;

	}


	s_PoseH ToAbg()
	{
		s_PoseH PoseH;

		try
		{
			HTuple h1, h2;

			h1.Clear();
			h1[0] = fTransX;
			h1[1] = fTransY;
			h1[2] = fTransZ;
			h1[3] = fRotX;
			h1[4] = fRotY;
			h1[5] = fRotZ;
			h1[6] = dwType;

			ConvertPoseType(h1, "Rp+T", "abg", "point", &h2);
			PoseH = s_PoseH(h2);

		}
		catch (HOperatorException ex)
		{

		}


		return PoseH;

	}


	//返回rt转换矩阵  刚性 HomMat3DIdentity is stored as the tuple [1,0,0,0,0,1,0,0,0,0,1,0].
	std::vector<double> getHomMat3dValues()
	{
		std::vector<double> valList;

		try
		{
			HTuple hv_HomMat3D;
			PoseToHomMat3d(s_PoseH(fTransX, fTransY, fTransZ, fRotX, fRotY, fRotZ, dwType).ToTuple(), &hv_HomMat3D);
			for (int i = 0; i < hv_HomMat3D.Length(); i++)
			{
				valList.push_back(hv_HomMat3D[i]);
			}
		}
		catch (HOperatorException ex)
		{
			valList.clear();
		}

		return valList;
	}

};

// 函数返回
struct s_Rtnf
{
public:
	int iCode = 0;                  // 返回代码
	std::string strInfo = "";                // 返回描述

};


